package com.aqie.demo.transaction_lost;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

@Service
public class SpringTransactionImpl implements ISpringTransaction {

    @Autowired
    private IdAndNameDao idAndNameDao;

    /**
     * 抛出异常被捕获 事务不会回滚
     * 手动标记回滚 编程式事务实现， 事务会回滚
     */
    @Override
    @Transactional
    public void CatchExceptionCanNotRollback() {

        try {
            idAndNameDao.save(new IdAndName("qinyi"));
            throw new RuntimeException();
        } catch (Exception ex) {
            ex.printStackTrace();
            // 手动标记回滚 编程式事务实现
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }

    /**
     * 抛出checked Exception 不能回滚
     * @throws CustomException
     */
    @Override
    @Transactional
    public void NotRuntimeExceptionCanNotRollback() throws CustomException {

        try {
            idAndNameDao.save(new IdAndName("qinyi"));
            throw new RuntimeException();
        } catch (Exception ex) {
            throw new CustomException(ex.getMessage());
        }
    }

    @Override
    @Transactional
    public void RuntimeExceptionCanRollback() {

        idAndNameDao.save(new IdAndName("qinyi"));
        throw new RuntimeException();
    }

    /**
     * rollbackFor 抛出 unchecked 异常 可以回滚
     * @throws CustomException
     */
    @Override
    @Transactional(rollbackFor = {CustomException.class})
    public void AssignExceptionCanRollback() throws CustomException {

        try {
            idAndNameDao.save(new IdAndName("qinyi"));
            throw new RuntimeException();
        } catch (Exception ex) {
            throw new CustomException(ex.getMessage());
        }
    }

    @Transactional
    public void anotherOneSaveMethod() {

        idAndNameDao.save(new IdAndName("qinyi"));
        throw new RuntimeException();
    }

    /**
     * 未标注事务方法 调用标注事务方法， 事务会失效
     */
    @Override
    public void NonTransactionalCanNotRollback() {

        anotherOneSaveMethod();
    }
}
